package com.thinkgem.jeesite.modules.sys.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.thinkgem.jeesite.common.persistence.BaseConstants;
import com.thinkgem.jeesite.common.service.ServiceException;
import com.thinkgem.jeesite.common.utils.SessionUtils;
import com.thinkgem.jeesite.modules.sys.dao.SysRoleMapper;
import com.thinkgem.jeesite.modules.sys.entity.SysRole;
import com.thinkgem.jeesite.modules.sys.entity.SysUser;
import com.thinkgem.jeesite.modules.sys.utils.UserUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @Author:Kongxiangsheng
 * @DesCription:
 * @Date:Created in 16:40 2018/8/12
 * @Modified By:
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class SysRoleService extends ServiceImpl<SysRoleMapper, SysRole> implements IService<SysRole> {
    @Autowired
    private SysMenuService sysMenuService;

    /**
     * 获取所有角色（含系统角色）
     *
     * @return
     */
    public List<SysRole> selectRollListAll() {
        QueryWrapper queryWrapper = new QueryWrapper(null);
        queryWrapper.orderByAsc(SysRole.COL_IS_SYS);
        return this.baseMapper.selectList(queryWrapper);
    }

    /**
     * 获取所有角色（不包含系统角色）
     *
     * @return
     */
    public List<SysRole> selectRollList() {
        QueryWrapper queryWrapper = new QueryWrapper(null);
        queryWrapper.eq(SysRole.COL_IS_SYS, BaseConstants.YES_NO_FLAG_N);
        return this.baseMapper.selectList(queryWrapper);
    }

    /**
     * 根据Id获取，并获取配置的菜单权限
     *
     * @param id
     * @return
     */
    public SysRole getWithMenu(String id) {
        SysRole sysRole = this.baseMapper.selectById(id);
        sysRole.setSysMenuList(sysMenuService.findByRoleId(id));
        return sysRole;
    }

    /**
     * 根据名称获取对象
     *
     * @param name
     * @return
     */
    public SysRole getByName(String name) {
        QueryWrapper queryWrapper = new QueryWrapper<SysRole>();
        queryWrapper.eq(SysRole.COL_NAME, name);
        return this.getOne(queryWrapper);
    }

    /**
     * 删除角色信息
     *
     * @param role
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteRole(SysRole role) {
        // 校验当前用户是否含有该角色
        SysUser sysUser = UserUtils.getUser();
        for (SysRole userRole : sysUser.getRoleList()) {
            if (userRole.getId().equals(role.getId())) {
                throw new ServiceException("不能删除自己拥有的角色！");
            }
        }
        // 删除用户角色关系
        this.baseMapper.deleteUserRole(role.getId());

        // 删除角色信息
        this.removeById(role.getId());

        // TODO: 查找拥有该角色的用户session，如果存在，则清空session数据并强制用户下线
        // TODO: 清除用户角色缓存
        SessionUtils.removeAttrRole();
    }

    /**
     * 保存角色信息
     *
     * @param sysRole
     * @return
     */
    @Transactional( rollbackFor = Exception.class)
    public boolean saveRole(SysRole sysRole) {
        if (StringUtils.isBlank(sysRole.getId())) {
            return this.insertRole(sysRole);
        }
        return this.updateRole(sysRole);
    }

    /**
     * 插入角色信息
     *
     * @param sysRole
     * @return
     */
    @Transactional( rollbackFor = Exception.class)
    public boolean insertRole(SysRole sysRole) {
        if (StringUtils.isBlank(sysRole.getIsSys())) {
            sysRole.setIsSys(BaseConstants.YES_NO_FLAG_N);
        }
        this.baseMapper.insert(sysRole);
        this.insertRoleMenu(sysRole);

        // TODO: 清除用户角色缓存
        SessionUtils.removeAttrRole();
        return true;
    }

    /**
     * 更新角色信息
     *
     * @param sysRole
     * @return
     */
    @Transactional( rollbackFor = Exception.class)
    public boolean updateRole(SysRole sysRole) {
        this.baseMapper.updateById(sysRole);

        // 更新角色与菜单关联
        this.deleteRoleMenu(sysRole.getId());
        if (CollectionUtils.isNotEmpty(sysRole.getSysMenuList())) {
            this.insertRoleMenu(sysRole);
        }

        // TODO: 查找拥有该角色的用户session，如果存在，则清空session数据并强制用户下线
        // TODO: 清除用户角色缓存
        SessionUtils.removeAttrRole();
        return true;
    }

    /**
     * 根据用户Id获取角色
     *
     * @param userId
     * @return
     */
    public List<SysRole> findByUserId(String userId) {
        return this.baseMapper.findByUserId(userId);
    }

    /**
     * 根据登录名获取角色
     *
     * @param loginName
     * @return
     */
    public List<SysRole> findByLoginName(String loginName) {
        return this.baseMapper.findByLoginName(loginName);
    }

    /**
     * 维护角色与菜单权限关系-添加
     *
     * @param role
     * @return
     */
    @Transactional( rollbackFor = Exception.class)
    public int insertRoleMenu(SysRole role) {
        if (CollectionUtils.isNotEmpty(role.getSysMenuList())) {
            return this.baseMapper.insertRoleMenu(role);
        }
        return 0;
    }

    /**
     * 维护角色与菜单权限关系-删除
     *
     * @param roleId
     * @return
     */
    @Transactional( rollbackFor = Exception.class)
    public int deleteRoleMenu(String roleId) {
        return this.baseMapper.deleteRoleMenu(roleId);
    }

    @Transactional( rollbackFor = Exception.class)
    public int insertUserRole(String userId, String roleId) {
        return this.baseMapper.insertOneUserRole(userId, roleId);
    }

    @Transactional( rollbackFor = Exception.class)
    public int deleteUserRole(String userId, String roleId) {
        return this.baseMapper.deleteOneUserRole(userId, roleId);
    }

}